/**
 * @FileName: ExecFilesHandler.java
 * @Author
 * @Description:
 * @Date 2016年3月15日 下午2:40:47
 * @CopyRight ZTE Corporation
 */
package cn.hpclub.server.controller.admin;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.core.ActionKey;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Model;

import cn.hpclub.server.model.SyncData;
import cn.hpclub.server.util.SystemConfigUtil;

public class DataSyncController<M extends Model<M>> extends Controller{
    private static final String ACTION_SYNC_DATA                = "4";
    private static final String ACTION_CALL_BACK                = "3";

    private static final String SERVICE_TYPE_LAST_DAY           = "1";                                              // 按天导出数据(上一天)
    private static final String SERVICE_TYPE_REWORD             = "2";                                              // 酬金
    private static final String SERVICE_TYPE_LAST_MONTH         = "3";                                              // 按天导出数据(上一月)
    private static final String SERVICE_TYPE_XUAN_HAO_RU_WANG   = "4";                                              // 选号入网
    private static final String SERVICE_TYPE_JIE_SHOU_WANG_DIAN = "5";

    private static final String KEY_FILE_URL                    = "FileUrl";
    private static final String KEY_FILE_NAME                   = "FileName";
    private static final String KEY_STATUS                      = "status";
    private static final String KEY_MESSAGE                     = "message";
    private static final String KEY_DIGEST                      = "digest";

    private static final String MSG_SUCCESS                     = "获取成功";
    private static final String MSG_ILLEGAL_PARAMETERS          = "参数错误";
    private static final String MSG_DATA_NOT_READY              = "数据未准备好，稍后再试";
    private static final String MSG_INTERANL_EXCEPTION          = "服务器内部错误";

    private static final int    STATUS_SUCCESS                  = 1000;
    private static final int    STATUS_NOT_READY                = 1001;
    private static final int    STATUS_INTERNAL_ERROR           = 1002;

    private static Logger       log                             = LoggerFactory.getLogger(DataSyncController.class);

    /**
     * @Title: execFilesHandler
     * @Description:同步请求接口
     * @param action请求类型:4同步请求，获取文件下载地址，3回调请求，文件下载完成
     * @param serviceType数据类型:1:按天导出数据(上一天);2:酬金;3:按天导出数据(上一月);4选号入网
     *            void
     */
    @ActionKey("/ExecFilesHandler")
    public void execFilesHandler(){
        log.info("execFilesHandler.action=" + getPara("action") + ",serviceType=" + getPara("serviceType"));
        String action = getPara("action");
        String serviceType = getPara("serviceType");

        if(StrKit.isBlank(action) || StrKit.isBlank(serviceType)){
            processParamError();
            return;
        }

        switch(action){
            case ACTION_SYNC_DATA:
                responseSyncData(serviceType);
                break;
            case ACTION_CALL_BACK:
                doCallBackup(serviceType, getPara("fileName"));
                break;
        }
    }

    /**
     * @Title: doCallBackup
     * @Description:同步完成回调
     * @param serviceType数据类型
     * @param fileName文件名
     *            void
     */
    private void doCallBackup(String serviceType, String fileName){
        String param = getPara();
        log.info("serviceType=" + param + ",fileName=" + fileName);
        JSONObject jo = new JSONObject();
        jo.put(KEY_STATUS, 1000);
        jo.put(KEY_MESSAGE, MSG_SUCCESS);
        renderJson(jo.toString());
    }

    /**
     * @Title: responseSyncData
     * @Description:获取同步信息
     * @param serviceType同步类型
     *            void
     */
    private void responseSyncData(String serviceType){
        switch(serviceType){
            case SERVICE_TYPE_LAST_DAY:
                syncData(getLastDayTag());
                break;
            case SERVICE_TYPE_REWORD:
                break;
            case SERVICE_TYPE_LAST_MONTH:
                syncData(getLastMonthTag());
                break;
            case SERVICE_TYPE_XUAN_HAO_RU_WANG:
                break;
            case SERVICE_TYPE_JIE_SHOU_WANG_DIAN:
                break;
            default:
                break;
        }
    }

    /**
     * @Title: processParamError
     * @Description:处理错误参数 void
     */
    private void processParamError(){
        JSONObject jo = new JSONObject();
        jo.put(KEY_STATUS, 1002);
        jo.put(KEY_MESSAGE, MSG_ILLEGAL_PARAMETERS);
        renderJson(jo.toString());
    }

    /**
     * @Title: syncData
     * @Description:返回同步数据 void
     */
    private void syncData(String tag){
        JSONArray ja = new JSONArray();
        JSONObject jo = new JSONObject();
        SyncData syncData = SyncData.dao.getSyncData(tag);
        int status = STATUS_SUCCESS;
        String message = "";
        try{
            if(null == syncData){
                status = STATUS_NOT_READY;
                message = MSG_DATA_NOT_READY;
            } else{
                message = MSG_SUCCESS;
                jo.put(KEY_FILE_URL, getFileUrl(syncData.getStr(KEY_DIGEST)));
                jo.put(KEY_FILE_NAME, syncData.getStr("file_name"));
            }
        }
        catch(Exception e){
            e.printStackTrace();
            status = STATUS_INTERNAL_ERROR;
            message = MSG_INTERANL_EXCEPTION;
        }
        jo.put(KEY_STATUS, status);
        jo.put(KEY_MESSAGE, message);
        ja.put(jo);
        renderJson(ja.toString());
    }

    /**
     * @Title: getFileUrl
     * @Description:获取文件URL路径
     * @param digest摘要
     * @return String文件URL路径
     */
    private String getFileUrl(String digest){
        String url = SystemConfigUtil.getSystemConfig().getHostPrefix() + "/Download?" + KEY_DIGEST + "=";
        log.info("url=" + url);
        String param = "";
        try{
            param = URLEncoder.encode(digest, "utf-8");
        }
        catch(UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return url + param;
    }

    /**
     * @Title: downloadFile
     * @Description:下载同步文件 void
     */
    @ActionKey("/Download")
    public void downloadFile(){
        String digest = getPara(KEY_DIGEST);
        log.info(KEY_DIGEST + "=" + digest);
        try{
            String path = getFilePath(digest);
            renderFile(new File(path));
        }
        catch(IOException e){
            e.printStackTrace();
            renderError(404);
        }
    }

    /**
     * @Title: getFilePath
     * @Description:根据摘要获取文件路径
     * @param digest
     *            摘要
     * @return 文件路径
     * @throws IOException
     *             String
     */
    private String getFilePath(String digest) throws IOException{
        if(null == digest){
            throw new IOException("digest is empty");
        }
        SyncData syncData = SyncData.dao.getSyncDataByDigest(digest);
        if(null == syncData){
            throw new IOException("syncData is null");
        }
        String path = syncData.getStr("path");
        if(StrKit.isBlank(path)){
            throw new IOException("path is empty");
        }
        return path;
    }

    /**
     * @Title: getLastDayTag
     * @Description:获取导出数据(上一天Tag) void
     */

    private String getLastDayTag(){
        SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -1);
        return dateFormater.format(calendar.getTime());
    }

    /**
     * @Title: getLastDayTag
     * @Description:获取导出数据(上一天Tag) void
     */
    private String getLastMonthTag(){
        SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        return dateFormater.format(calendar.getTime());
    }

}
